#ifndef TEST_TYPES_INCLUDED
#define TEST_TYPES_INCLUDED

#ifdef WIN32
#ifdef test_lib_EXPORTS
#define TESTLIB_API __declspec(dllexport)
#else
#define TESTLIB_API __declspec(dllimport)
#endif
#else
#define TESTLIB_API
#endif

namespace shared_test_lib {
    struct TESTLIB_API big_data final {
        explicit big_data();

        double a;
        float b;
        int data[1024];
    };

    struct TESTLIB_API small_data final {
        explicit small_data();

        int i;
    };
}


#define CHECK(x) ((x)? (void)(0) : (void(fprintf(stdout, "Failed at %d:%s: %s\n", __LINE__, __FILE__, #x)), std::exit(EXIT_FAILURE)))

template<size_t N>
struct words
{
    void* w[N];
};

struct big_type
{
    char i_wanna_be_big[256];
    std::string value;

    big_type() :
            value(std::string(300, 'b'))
    {
        i_wanna_be_big[0] = i_wanna_be_big[50] = 'k';
    }

    bool check()
    {
        CHECK(value.size() == 300);
        CHECK(value.front() == 'b' && value.back() == 'b');
        CHECK(i_wanna_be_big[0] == 'k' && i_wanna_be_big[50] == 'k');
        return true;
    }
};

// small type which has nothrow move ctor but throw copy ctor
struct regression1_type
{
    const void* confuse_stack_storage = (void*)(0);
    regression1_type() {}
    regression1_type(const regression1_type&) {}
    regression1_type(regression1_type&&) noexcept {}
    regression1_type& operator=(const regression1_type&) { return *this; }
    regression1_type& operator=(regression1_type&&) { return *this; }
};

#endif
